/*********************************************************
          File Name:us.cpp
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Sat 19 Sep 2015 09:08:53 PM CST
**********************************************************/

#include "us.h"

using std::shared_ptr;

int main()
{
        shared_ptr<TY> ty = std::make_shared<TY>("taeyeon", 26, "Kim Taeyeon", "Female");
        //TY ty1("Kim Taeyeon", "Female");
        //TY ty1(ty);
        shared_ptr<Human> human = std::make_shared<Human>("Taeyeon", 27);

        std::cout << "show use of dynamic type, use which version of"
                " `getname()` is determined when running\n";

        print_info(ty); // static type `Hunam &`, dynamic type `TY`
        print_info(human); // static type `Hunam &`, dynamic type `Human`

        AC ac("abby", 23, "Abby Cin", "Male");
/*
        std::cout << ac.getage() << std::endl;
        std::cout << ac.getname() << std::endl; // call in AC
        std::cout << ac.Human::getname() << std::endl; // call in Human
        std::cout << ac.getgender() << std::endl;
*/
        Human h("ty", 26);

        AC *ac1 = new AC(ac);
        Human *h2 = ac1;

        std::cout << "\e[45m--------------------------------\e[0m\n";

        std::cout << "\e[36m\e[1mdynamic binding\e[0m \e[36mcall the same "
                "version of virtual function `getname()`\e[0m\n";

        // derived class call its own method
        std::cout << "\e[31mcall `ac1->getname()`\e[0m " << ac1->getname() << std::endl;

        // base class call derived class method
        std::cout << "\e[31mcall `h2->getname()`\e[0m " << h2->getname() << std::endl;

        std::cout << "\e[36m\e[1mstatic binding\e[0m \e[36mcall it's own "
                "version function `getage()`\e[0m\n";

        std::cout << ac1->getage() << std::endl;
        std::cout << h2->getage() << std::endl;


        std::cout << "\e[45m--------------------------------\e[0m\n";
        std::cout << "\e[32mavoiding use dynamic binding,"
                " use `::` to call specific version of function\e[0m\n";
        std::cout << ac1->Human::getname() << std::endl;

        delete ac1;

        print_info(ty);
        print_info(h);

        //TY kk = Human("ty", 26);     // wrong
        //TY *mm = new Human("ty", 26);   // wrong
        

        return 0;
}
